package Client;

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import javax.swing.*;

import org.gibello.zql.ParseException;
import org.gibello.zql.ZStatement;
import org.gibello.zql.ZqlParser;


import java.io.ByteArrayInputStream;

import java.io.IOException;
import java.io.InputStream;

import java.io.UnsupportedEncodingException;

/**
 * Frame chương trình chính từ client.
 */
public class ClientGUI extends JFrame implements ActionListener 
{
	private JPanel contentPane;
	private JLabel lblTrangThai;
	private JTextArea textAreaNhapTruyVan;
	private JButton btnGuiTruyVan;
	private JButton btnNgatKetNoi;

		
	boolean ngatKetNoi = false;
	
	private static SocketClient socketClient;
	private JTextArea textAreaLichSuTruyVan;
	
	private CurrentTimer timer;
	private JScrollPane scrollPanelKetQua;

	private boolean sanSangKetNoi = false;

	/**
	 * Chạy ứng dụng.
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		ClientGUI frameClient = new ClientGUI();
		socketClient = new SocketClient(frameClient);
	}

	/**
	 * Tạo giao diện GUI.
	 */
	public ClientGUI() {
		setTitle("Client Control");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 890, 591);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JLabel lblNhpCuLnh = new JLabel("Nhập câu truy vấn SQL");
		lblNhpCuLnh.setForeground(Color.BLUE);
		lblNhpCuLnh.setFont(new Font("Tahoma", Font.BOLD, 14));
		lblNhpCuLnh.setBounds(10, 12, 226, 30);
		contentPane.add(lblNhpCuLnh);
		
		JScrollPane scrollPaneNhapLenh = new JScrollPane();
		scrollPaneNhapLenh.setBounds(10, 53, 245, 136);
		contentPane.add(scrollPaneNhapLenh);
		
		textAreaNhapTruyVan = new JTextArea();
		textAreaNhapTruyVan.setForeground(Color.BLACK);
		textAreaNhapTruyVan.setBackground(Color.WHITE);
		textAreaNhapTruyVan.setLineWrap(true);
		scrollPaneNhapLenh.setViewportView(textAreaNhapTruyVan);
		
		btnGuiTruyVan = new JButton("");
		btnGuiTruyVan.setIcon(new ImageIcon(ClientGUI.class.getResource("/ImagesSource/rsz_send.png")));
		btnGuiTruyVan.setToolTipText("Gửi truy vấn");
		btnGuiTruyVan.setBounds(10, 209, 51, 38);
		contentPane.add(btnGuiTruyVan);
		
		scrollPanelKetQua = new JScrollPane();
		scrollPanelKetQua.setBounds(297, 55, 575, 484);
		contentPane.add(scrollPanelKetQua);
		
		JLabel lblKtQu = new JLabel("Kết quả");
		lblKtQu.setForeground(Color.BLUE);
		lblKtQu.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblKtQu.setBounds(297, 11, 107, 33);
		contentPane.add(lblKtQu);
		
		setLblTrangThai(new JLabel(""));
		getLblTrangThai().setBounds(10, 509, 277, 30);
		contentPane.add(getLblTrangThai());
		setVisible(false);
		
		btnNgatKetNoi = new JButton("");
		btnNgatKetNoi.setIcon(new ImageIcon(ClientGUI.class.getResource("/ImagesSource/rsz_disconnect.png")));
		btnNgatKetNoi.setToolTipText("Ngắt kết nối");
		btnNgatKetNoi.setActionCommand("GuiTruyVan");
		btnNgatKetNoi.setBounds(204, 209, 51, 38);
		contentPane.add(btnNgatKetNoi);
		
		btnGuiTruyVan.setActionCommand("GuiTruyVan");
		btnNgatKetNoi.setActionCommand("NgatKetNoi");
		
		JLabel lblLichSuTruyVan = new JLabel("Lịch sử truy vấn");
		lblLichSuTruyVan.setForeground(Color.BLUE);
		lblLichSuTruyVan.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblLichSuTruyVan.setBounds(10, 258, 245, 33);
		contentPane.add(lblLichSuTruyVan);
		
		JScrollPane scrollPaneLichSuTruyVan = new JScrollPane();
		scrollPaneLichSuTruyVan.setBounds(10, 302, 245, 196);
		contentPane.add(scrollPaneLichSuTruyVan);
		
		textAreaLichSuTruyVan = new JTextArea();
		textAreaLichSuTruyVan.setEditable(false);
		textAreaLichSuTruyVan.setLineWrap(true);
		textAreaLichSuTruyVan.setForeground(Color.WHITE);
		textAreaLichSuTruyVan.setBackground(Color.BLACK);
		scrollPaneLichSuTruyVan.setViewportView(textAreaLichSuTruyVan);
		
		
		
		btnGuiTruyVan.addActionListener(this);
		btnNgatKetNoi.addActionListener(this);
		
		timer = new CurrentTimer();
		
		// Khởi tạo form đăng nhập
		new Login(this);
	}

	/**
	 * Xử lý lệnh
	 */
	public int getLoaiTruyVan(String cauSQL)
	{
		InputStream is = null;
		try {
			is = new ByteArrayInputStream(
					cauSQL.getBytes("Cp1252"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		ZqlParser parser = new ZqlParser(is);
		try {
			ZStatement st = parser.readStatement();
		} catch (ParseException e){
			
			return -1;
		}
		cauSQL = cauSQL.toLowerCase();
		if(cauSQL.contains("select") && cauSQL.contains("from"))// câu select
			return 1;
		if(cauSQL.contains("insert into") && cauSQL.contains("values") )//câu insert
			return 2;
		if(cauSQL.contains("update") && cauSQL.contains("set") && cauSQL.contains("where"))//câu update
			return 3;
		if(cauSQL.contains("delete from") &&  cauSQL.contains("where"))//câu delete
			return 4;
		return -1;
	}
	@Override
	public void actionPerformed(ActionEvent e) 
	{
		/**
		 * Gửi câu truy vấn
		 */
		if (e.getActionCommand().equals("GuiTruyVan")) {
			try
			{ 
				if(ngatKetNoi == false)
				{
				getSocketClient().sentMessage = textAreaNhapTruyVan.getText();
				getSocketClient().bw.write(getSocketClient().sentMessage);
				getSocketClient().bw.newLine();
				getSocketClient().bw.flush();
				textAreaLichSuTruyVan.append(timer.currentTime + textAreaNhapTruyVan.getText() + "\n");
				String cauTruyVan = textAreaNhapTruyVan.getText().toLowerCase()+";";
				int loaiTruyVan = getLoaiTruyVan(cauTruyVan);
				switch (loaiTruyVan) {
				
				case 1:	if(kiemTraKetNoi())// kết nối còn
				{
						textAreaLichSuTruyVan.append(timer.currentTime + "Đã thực hiện truy vấn Select\n");
						nhanKetQua();
						break;
				}
				case 2:	if(kiemTraKetNoi())
				{
					textAreaLichSuTruyVan.append(timer.currentTime + "Đã thực hiện truy vấn Insert \n");
						nhanKetQua();
						break;
				}
				case 3:if(kiemTraKetNoi())
				{
					textAreaLichSuTruyVan.append(timer.currentTime + "Đã thực hiện truy vấn Update \n");
						nhanKetQua();
						break;
				}
				case 4:if(kiemTraKetNoi())
					{
					textAreaLichSuTruyVan.append(timer.currentTime + "Đã thực hiện truy vấn Delete \n");
					nhanKetQua();
					break;
					}
						
				default:
					JOptionPane.showMessageDialog(this, "Không đúng cú pháp SQL!!!");
				}
				}
				else
					JOptionPane.showMessageDialog(this, "Đã ngắt kết nối");
				textAreaNhapTruyVan.setText("");
				
			}
			catch(IOException message)
			{
				JOptionPane.showMessageDialog(this, message.toString(), "Lỗi kết nối", JOptionPane.ERROR_MESSAGE);
			}
		}
		
		
		/**
		 * Xử lý ngắt kết nối.
		 */
		if (e.getActionCommand().equals("NgatKetNoi"))
		{
			try {
				getSocketClient().bw.write("quit");
				getSocketClient().bw.close();
				getSocketClient().br.close();
				getLblTrangThai().setText("Đã ngắt kết nối với server");
			} catch (IOException e1) {
				JOptionPane.showMessageDialog(this, e1.toString(), "Lỗi trong quá trình ngắt kết nối", JOptionPane.ERROR_MESSAGE);
			}
		}
	}
	public void nhanKetQua()
	{
		Server.BangXML bangXML;
		getSocketClient().createInputObject();
		
		Object objPhanHoi;
	
		try {
			
				
			objPhanHoi = getSocketClient().ois.readObject();
			if(objPhanHoi instanceof String)
			{
				JOptionPane.showMessageDialog(this, objPhanHoi.toString());
				
			}
			else
			{				
				bangXML = (Server.BangXML)objPhanHoi;		
				Server.MyTable myTable = new Server.MyTable(200, 100, bangXML.getData(), bangXML.getNames(),
								bangXML.getTypeData(),bangXML.getTableName(),bangXML.getKhoaChinh());
				scrollPanelKetQua.setViewportView(myTable);
				scrollPanelKetQua.validate();

			}
			
		} 
		catch (ClassNotFoundException e1) 
		{
			JOptionPane.showMessageDialog(this, e1.toString(), "Lỗi trong quá trình truy vấn", JOptionPane.ERROR_MESSAGE);
		} catch (IOException e1) 
		{
			JOptionPane.showMessageDialog(this, e1.toString(), "Lỗi trong quá trình truy vấn", JOptionPane.ERROR_MESSAGE);
		}
	}
	/**
	 * @return the lblTrangThai
	 */
	public JLabel getLblTrangThai() {
		return lblTrangThai;
	}

	/**
	 * @param lblTrangThai the lblTrangThai to set
	 */
	public void setLblTrangThai(JLabel lblTrangThai) {
		this.lblTrangThai = lblTrangThai;
		lblTrangThai.setForeground(Color.RED);
		lblTrangThai.setFont(new Font("Tahoma", Font.BOLD | Font.ITALIC, 13));
	}

	/**
	 * @return the socketClient
	 */
	public static SocketClient getSocketClient() {
		return socketClient;
	}

	/**
	 * @param socketClient the socketClient to set
	 */
	public static void setSocketClient(SocketClient socketClient) {
		ClientGUI.socketClient = socketClient;
	}
	public boolean kiemTraKetNoi ()
	   {
		   String tinhTrangKetNoi;
		   getSocketClient().createInputObject();
		   try {
			tinhTrangKetNoi = (String)getSocketClient().ois.readObject();
			System.out.println(tinhTrangKetNoi);
			if(!tinhTrangKetNoi.equals("VanKetNoi"))
			{
				ngatKetNoi = true;
				return false;
			}
		} catch (ClassNotFoundException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
			
		   return true;
	   }

	/**
	 * @return the sanSangKetNoi
	 */
	public boolean isSanSangKetNoi() {
		return sanSangKetNoi;
	}

	/**
	 * @param sanSangKetNoi the sanSangKetNoi to set
	 */
	public void setSanSangKetNoi(boolean sanSangKetNoi) {
		this.sanSangKetNoi = sanSangKetNoi;
	}
}

/**
 * Frame hỗ trợ việc đăng nhập từ Client
 */
class Login extends JFrame implements ActionListener
{
	final JButton btnKetNoiServer;
	final JPanel panel;
	final JLabel lblIpServer;
	final JLabel lblPort;
	final JTextField  fieldIpServer;
	final JTextField fieldPortServer;
	
	private String TEN_HOST = "localhost";
	private String PORT_HOST = "3200";
	
	ClientGUI frameChinh;
	
	/**
	 * Vẽ form đăng nhập
	 * @param form Client chính
	 */
	Login(ClientGUI masterForm)
	{
		super("Login Form");
		frameChinh = masterForm;
		lblIpServer = new JLabel("IP Server: ");
		fieldIpServer = new JTextField(20);

		lblPort = new JLabel("Port Server : ");
		fieldPortServer = new JTextField(15);

		btnKetNoiServer = new JButton("Kết nối server");
		btnKetNoiServer.setActionCommand("KetNoiServer");
		btnKetNoiServer.addActionListener(this);
		
		panel = new JPanel(new GridLayout(3,2));
		panel.setLocation(new Point(300, 500));
		panel.add(lblIpServer);
		panel.add(fieldIpServer);
		panel.add(lblPort);
		panel.add(fieldPortServer);
		panel.add(btnKetNoiServer);
		// to fill the GridLayout
		panel.add(new JLabel(""));
		add(panel,BorderLayout.CENTER);

		setTitle("ĐĂNG NHẬP");
		setSize(300,100);
		setVisible(true);
		setLocation(new Point(550, 250));
	}
	
    public void actionPerformed(ActionEvent ee)
	{
    	if (ee.getActionCommand().equals("KetNoiServer"))
    	{
			if(fieldIpServer.getText().equals(TEN_HOST)) {
				if(fieldPortServer.getText().equals(PORT_HOST)) {
					frameChinh.setSanSangKetNoi(true);
					ClientGUI.setSocketClient(new SocketClient(frameChinh));
					if (ClientGUI.getSocketClient().isSanSangKetNoi() == true)
					{
						this.setVisible(false);				// Ẩn form login
						frameChinh.setVisible(true);		// Hiện form client
						this.dispose();						// Xóa form login
					}
					return;
				}
    		}
			//Thông báo lỗi khi đăng nhập thất bại
			JOptionPane.showMessageDialog(this, "Đăng nhập thất bại do sai IpServer/Mật khẩu\n Thử lại", "Lỗi đăng nhập", JOptionPane.ERROR_MESSAGE);
	    }
	}
   
}